package com.sj.parksdk.fragment.park;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.android.vlayout.layout.LinearLayoutHelper;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.TextureMapView;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;
import com.baidu.mapapi.search.sug.SuggestionResult;
import com.baidu.mapapi.search.sug.SuggestionSearch;
import com.baidu.mapapi.search.sug.SuggestionSearchOption;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.sj.parksdk.R;
import com.sj.parksdk.R2;
import com.sj.parksdk.adapter.base.delegate.SimpleDelegateAdapter;
import com.sj.parksdk.core.BaseFragment;
import com.sj.parksdk.net.http.MyNetApi;
import com.sj.parksdk.net.http.callback.TipRequestCallBack;
import com.sj.parksdk.net.request.MGetRequest;
import com.sj.parksdk.net.result.databean.Data_NearbyPark;
import com.sj.parksdk.setting.Dictionary;
import com.sj.parksdk.utils.NavicatUtils;
import com.sj.parksdk.utils.Utils;
import com.sj.parksdk.utils.XToastUtils;
import com.sj.parksdk.utils.bdlocation.LocatedInfo;
import com.sj.parksdk.utils.bdlocation.LocationService;
import com.sj.parksdk.utils.bdlocation.LocationUtils;
import com.sj.parksdk.widget.sweetalert.SweetAlertDialog;
import com.xuexiang.xhttp2.exception.ApiException;
import com.xuexiang.xhttp2.request.GetRequest;
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xpage.enums.CoreAnim;
import com.xuexiang.xui.adapter.recyclerview.RecyclerViewHolder;
import com.xuexiang.xui.utils.DensityUtils;
import com.xuexiang.xui.utils.ResUtils;
import com.xuexiang.xui.utils.WidgetUtils;
import com.xuexiang.xui.widget.layout.XUILinearLayout;
import com.xuexiang.xui.widget.statelayout.CustomStateOptions;
import com.xuexiang.xui.widget.statelayout.StatefulLayout;
import com.xuexiang.xutil.common.StringUtils;
import com.xuexiang.xutil.display.ImageUtils;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

@Page(anim = CoreAnim.none)
public class FragmentPark extends BaseFragment {
    @BindView(R2.id.bmapView)
    TextureMapView mMapView;
    @BindView(R2.id.et_search)
    EditText etSearch;
    @BindView(R2.id.recycler_bearby_park)
    RecyclerView recyclerBearbyPark;
    @BindView(R2.id.bottom_sheet)
    XUILinearLayout bottomSheet;
    @BindView(R2.id.rg_park_type)
    RadioGroup rgParkType;
    @BindView(R2.id.xll_map_search)
    XUILinearLayout xllMapSearch;
    @BindView(R2.id.iv_search_clear)
    ImageView ivSearchClear;
    @BindView(R2.id.tv_search_bt)
    TextView tvSearchBt;
    @BindView(R2.id.iv_pull)
    ImageView ivPull;
    @BindView(R2.id.recycler_suggession)
    RecyclerView recyclerSuggession;
    @BindView(R2.id.ll_state_suggession)
    StatefulLayout llStateSuggession;
    @BindView(R2.id.ll_state_nearby)
    StatefulLayout llStateNearby;
    @BindView(R2.id.xll_suggession)
    XUILinearLayout xllSuggession;
    private BottomSheetBehavior bottomSheetBehavior;

    private BaiduMap mBaiduMap = null;

    private SuggestionSearch mSuggestionSearch = null;

    private SimpleDelegateAdapter<Data_NearbyPark> adapterNearby;
    private SimpleDelegateAdapter<Data_NearbyPark> adapterDialog;

    private SimpleDelegateAdapter<SuggestionResult.SuggestionInfo> adapterSuggestion;
    private boolean target = false;//是否为目标点


    @Override
    protected int getLayoutId() {
        return R.layout.parksdk_fragment_map;
    }

    @Override
    protected void initViews() {
        initMap();
        initAdapter();
    }

    private void initAdapter() {
        adapterNearby = new SimpleDelegateAdapter<Data_NearbyPark>(R.layout.parksdk_adapter_map_nearby_park, new LinearLayoutHelper()) {
            @Override
            protected void bindData(@NonNull RecyclerViewHolder holder, int position, Data_NearbyPark item) {
                holder.text(R.id.tv_name, item.getName());
                holder.text(R.id.tv_address, item.getDistanceStr() + " I " + item.getAddress());
                holder.text(R.id.rtv_charge, "收费标准:" + item.getChargeStandard());
                holder.text(R.id.tv_park_remain, Html.fromHtml(getParkRemainStr(item)));
                holder.click(R.id.rtv_navigation, v -> navigatToPark(item));
                holder.click(R.id.rl_content, v -> showParkContentDialog(item));
            }
        };
        WidgetUtils.initRecyclerView(recyclerBearbyPark, 0);
        recyclerBearbyPark.setAdapter(adapterNearby);

        adapterDialog = new SimpleDelegateAdapter<Data_NearbyPark>(R.layout.parksdk_adapter_dialog_park_content, new LinearLayoutHelper()) {
            @Override
            protected void bindData(@NonNull RecyclerViewHolder holder, int position, Data_NearbyPark item) {
                holder.text(R.id.tv_name, item.getName());
                holder.text(R.id.tv_address, item.getDistanceStr() + " I " + item.getAddress());
                holder.text(R.id.tv_park_remain, Html.fromHtml(getParkRemainStr(item)));
                holder.text(R.id.tv_charge, item.getChargeStandard());
            }
        };
        adapterSuggestion = new SimpleDelegateAdapter<SuggestionResult.SuggestionInfo>(R.layout.parksdk_adapter_map_suggession, new LinearLayoutHelper()) {
            @Override
            protected void bindData(@NonNull RecyclerViewHolder holder, int position, SuggestionResult.SuggestionInfo item) {
                holder.text(R.id.tv_name, item.getKey());
                holder.visible(R.id.tv_address, StringUtils.isEmpty(item.getAddress()) ? View.GONE : View.VISIBLE);
                holder.text(R.id.tv_address, item.getAddress());
                holder.click(R.id.item_suggestion, v -> moveToTarget(item));
            }
        };
        WidgetUtils.initRecyclerView(recyclerSuggession, DensityUtils.dp2px(1), ResUtils.getColor(R.color.color_cut_line));
        recyclerSuggession.setAdapter(adapterSuggestion);
    }

    private void moveToTarget(SuggestionResult.SuggestionInfo suggestInfo) {
        if (null == suggestInfo) {
            return;
        }
        if (null == mMapView) {
            return;
        }
        xllSuggession.setVisibility(View.GONE);
        tvSearchBt.setVisibility(View.GONE);
        LatLng latLng = suggestInfo.getPt();
        target = true;
        updateLocCenter(new LocatedInfo(suggestInfo.getAddress(), latLng.longitude, latLng.latitude));
    }

    private void showParkContentDialog(Data_NearbyPark item) {
        if (LocationUtils.isValidLocation(item.getLongitude(), item.getLatitude())) {
            LatLng latLng = new LatLng(item.getLatitude(), item.getLongitude());
            MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
            mBaiduMap.setMapStatus(msu);
        }
        List<Data_NearbyPark> list = new ArrayList<>();
        list.add(item);
        adapterDialog.refresh(list);
        new SweetAlertDialog(getContext(), SweetAlertDialog.RECYCLER_TYPE)
                .setTitleGone(true)
                .setRecyclerAdapter(adapterDialog, new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false))
                .setContentText(null)
                .setConfirmText("到这去")
                .setCancelClickListener(null)
                .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
                    @Override
                    public void onClick(SweetAlertDialog sDialog) {
                        sDialog.dismiss();
                        navigatToPark(item);
                    }
                })
                .show();
    }

    private String getParkRemainStr(Data_NearbyPark item) {
        StringBuffer sb = new StringBuffer();
        int state = item.getStatus();
        switch (state) {
            case Dictionary.Park.Park_Colose:
                sb.append("已停用");
                break;
            case Dictionary.Park.Park_Green:
                sb.append("<font color=\"#07C160\">");
                break;
            case Dictionary.Park.Park_Red:
                sb.append("<font color=\"#E84C47\">");
                break;
        }
        if (state == Dictionary.Park.Park_Colose) return sb.toString();
        sb.append("剩余泊位:")
                .append(item.getRemainSpace())
                .append("</font>")
                .append("/").append(item.getTotalSpace());
        return sb.toString();
    }

    /**
     * 导航去目标车场
     *
     * @param item
     */
    private void navigatToPark(Data_NearbyPark item) {
        NavicatUtils.navigat(item.getLongitude(), item.getLatitude(), item.getAddress(), getContext());
    }

    @Override
    protected void initData() {

    }

    @Override
    protected void initListeners() {
        initBottomSheet();
        initRadioGroup();
        initSearchListener();
    }

    private String keyword = "";//停车场关键词

    private void initSearchListener() {
        etSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (StringUtils.isEmpty(s.toString().trim())) {
                    keyword = "";
                    ivSearchClear.setVisibility(View.GONE);
                    tvSearchBt.setVisibility(View.GONE);
                    xllSuggession.setVisibility(View.GONE);
                    return;
                }
                ivSearchClear.setVisibility(View.VISIBLE);
                tvSearchBt.setVisibility(View.VISIBLE);
                keyword = s.toString().trim();
                etSearch.setSelection(s.toString().length());
            }
        });
        etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                    //点击搜索的时候隐藏软键盘
                    Utils.hideKeyboard(etSearch);
                    // 在这里写搜索的操作,一般都是网络请求数据
                    keyword = etSearch.getText().toString();
                    searchSuggession();
                    return true;
                }
                return false;
            }
        });
    }

    private void searchSuggession() {
//        String city = LocationService.get().getLocatedInfo().getCityName();
        String city = "淮安市";
        if (StringUtils.isEmpty(city)) {
            XToastUtils.warning("当前城市信息未知");
            return;
        }
        if (StringUtils.isEmpty(keyword)) {
            XToastUtils.warning("请输入搜索目标");
            return;
        }
        mSuggestionSearch.requestSuggestion(new SuggestionSearchOption()
                .city(city)
                .keyword(keyword)
                .citylimit(true));
    }

    private OnGetSuggestionResultListener suggestionResultListener = new OnGetSuggestionResultListener() {
        @Override
        public void onGetSuggestionResult(SuggestionResult suggestionResult) {
            xllSuggession.setVisibility(View.VISIBLE);
            if (suggestionResult == null
                    || suggestionResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
//                mLoadIndex = 0;
                llStateSuggession.showCustom(new CustomStateOptions().message("\n\n——没有搜索结果——"));
                return;
            }
            List<SuggestionResult.SuggestionInfo> suggesInfos = suggestionResult.getAllSuggestions();
            if (null == suggesInfos || suggesInfos.size() == 0) {
                llStateSuggession.showCustom(new CustomStateOptions().message("\n\n——没有搜索结果——"));
                return;
            }
            xllSuggession.setVisibility(View.VISIBLE);
            llStateSuggession.showContent();
            adapterSuggestion.refresh(suggesInfos);
            llStateSuggession.showContent();
        }
    };

    private void initBottomSheet() {
        int height = Utils.getWindowHeight();
        int bottomSheetHeight = height -DensityUtils.dp2px(140);
        ViewGroup.LayoutParams lp = bottomSheet.getLayoutParams();
        lp.height = bottomSheetHeight;
        bottomSheet.setLayoutParams(lp);
        bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        bottomSheetBehavior.setHideable(true);
        bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            }
        });
    }

    private int category = -1;

    private void initRadioGroup() {
        rgParkType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (checkedId == R.id.rb_park_all) {
                    category = -1;
                } else if (checkedId == R.id.rb_park_in) {
                    category = 1;
                } else if (checkedId == R.id.rb_park_road) {
                    category = 0;
                }
                searchNearByPark();
            }
        });
    }


    private void searchNearByPark() {
        GetRequest request = new MGetRequest(MyNetApi.PARK_LOTS_NEARBY)
                .visit()
                .params(MyNetApi.PakLotsNearby.longitude, LocationService.get().getLocatedInfo().getmLongitude())
                .params(MyNetApi.PakLotsNearby.latitude, LocationService.get().getLocatedInfo().getmLatitude())
                .params(MyNetApi.PakLotsNearby.range, 5.0)
                .params(MyNetApi.PakLotsNearby.pageIndex, 1)
                .params(MyNetApi.PakLotsNearby.pageSize, 100)
                .params(MyNetApi.PakLotsNearby.coordinateType, "BD09")
                .params(MyNetApi.PakLotsNearby.keyword, keyword);
        if (category != -1) {
            request.params(MyNetApi.PakLotsNearby.category, category);
        }
        request.execute(new TipRequestCallBack<Data_NearbyPark>() {
            @Override
            public void onSuccess(Data_NearbyPark data) throws Throwable {
                if (data.getItems() == null) {
                    llStateNearby.showCustom(new CustomStateOptions().message("\n\n——附近没有车位——"));
                    return;
                }
                if(data.getItems().size() == 0)llStateNearby.showCustom(new CustomStateOptions().message("\n\n——附近没有车位——"));
                else {
                    llStateNearby.showContent();
                    adapterNearby.refresh(data.getItems());
                    addMapMakers(data.getItems());
                }
            }

            @Override
            public void onError(ApiException e) {
                super.onError(e);
                llStateNearby.showCustom(new CustomStateOptions().message("\n\n——附件没有车位——"));
            }
        });
    }

    private void addMapMakers(List<Data_NearbyPark> items) {
        mBaiduMap.clear();
        //构建Marker图标
        for (int i = 0; i < items.size(); i++) {
            Data_NearbyPark park = items.get(i);
            if (!LocationUtils.isValidLocation(park.getLongitude(), park.getLatitude())) continue;
            LatLng point = new LatLng(park.getLatitude(), park.getLongitude());
            int state = park.getStatus();
            BitmapDescriptor bitmap = null;
            switch (state) {
                case Dictionary.Park.Park_Colose:
                    bitmap = getBitmapDescriptor(R.mipmap.park_ic_map_park_gray);
                    break;
                case Dictionary.Park.Park_Green:
                    bitmap = getBitmapDescriptor(R.mipmap.park_ic_map_park_green);
                    break;
                case Dictionary.Park.Park_Red:
                    bitmap = getBitmapDescriptor(R.mipmap.park_ic_map_park_red);
                    break;
                default:
                    bitmap = getBitmapDescriptor(R.mipmap.park_ic_map_park);
                    break;
            }
            OverlayOptions option = new MarkerOptions()
                    .position(point)
                    .icon(bitmap)
                    .zIndex(9) // 设置marker所在层级
                    .draggable(true); // 设置手势拖拽;
            Marker marker = (Marker) mBaiduMap.addOverlay(option);
            Bundle bundle = new Bundle();
            //info必须实现序列化接口
            bundle.putInt("position", i);
            marker.setExtraInfo(bundle);
        }
    }

    private BitmapDescriptor getBitmapDescriptor(int resId) {
        return getBitmapDescriptor(resId,0.5f,0.5f);
    }

    private BitmapDescriptor getBitmapDescriptor(int resId, float s_h, float s_w) {

        Bitmap bitmap = ImageUtils.compressByScale(ImageUtils.getBitmap(resId),s_w,s_h,true);
        BitmapDescriptor bd = BitmapDescriptorFactory.fromBitmap(bitmap);
        if (bitmap.isRecycled()) {
            bitmap.recycle();
        }
        return bd;
    }


    private void initMap() {
        mBaiduMap = mMapView.getMap();
        //开启地图的定位图层
        mBaiduMap.setMyLocationEnabled(true);

        //普通地图
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);

        //开启交通图
        mBaiduMap.setTrafficEnabled(true);
        //关闭缩放按钮
        mMapView.showZoomControls(false);
        //定位图标样式
        setMapCenterIcon();
        //marker点击事件
        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                Bundle bundle = marker.getExtraInfo();
                int position = bundle.getInt("position", -1);
                if (position == -1) return false;
                if (adapterNearby == null || adapterNearby.getData() == null || adapterNearby.getData().size() == 0)
                    return false;
                Data_NearbyPark item = adapterNearby.getData().get(position);
                showParkContentDialog(item);
                return true;
            }
        });

        mSuggestionSearch = SuggestionSearch.newInstance();
        mSuggestionSearch.setOnGetSuggestionResultListener(suggestionResultListener);
    }

    private void setMapCenterIcon() {
        //定位图标样式
        BitmapDescriptor bitmap = null;
        if (!target)  bitmap = getBitmapDescriptor(R.mipmap.park_ic_location);
        MyLocationConfiguration myLocationConfiguration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, false, bitmap);
        myLocationConfiguration.accuracyCircleFillColor = 0x00000000;
        myLocationConfiguration.accuracyCircleStrokeColor = 0x00000000;
        mBaiduMap.setMyLocationConfiguration(myLocationConfiguration);
    }

    public void updateLocData(LocatedInfo info) {
        if (info == null) return;
        setPosition2Center(info);
        category = -1;
        rgParkType.check(R.id.rb_park_all);
    }

    public void updateLocCenter(LocatedInfo info) {
        if (info == null) return;
        setPosition2Center(info);
        searchNearByPark();
    }

    /**
     * 设置中心点和添加marker
     */
    public void setPosition2Center(LocatedInfo info) {
        MyLocationData locData = new MyLocationData.Builder()
                .direction(0f)
                .latitude(info.getmLatitude())
                .longitude(info.getmLongitude()).build();
        mBaiduMap.setMyLocationData(locData);

        LatLng ll = new LatLng(info.getmLatitude(), info.getmLongitude());
        //构建中心点Marker图标
        setMapCenterIcon();
        MapStatus.Builder builder = new MapStatus.Builder();
        builder.target(ll).zoom(18.0f);
        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        target = false;
    }

    @Override
    public void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mBaiduMap.setMyLocationEnabled(true);
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 关闭定位图层
        if (null != mBaiduMap) {
            mBaiduMap.setMyLocationEnabled(false);
        }
        if(null != mMapView){
            mMapView.onDestroy();
            mMapView = null;
        }
        if (null != mSuggestionSearch) {
            mSuggestionSearch.destroy();
        }
    }

    @OnClick({R2.id.iv_search_clear, R2.id.tv_search_bt, R2.id.iv_moto_center})
    public void onViewClicked(View view) {
        int id = view.getId();
        if (id == R.id.iv_search_clear) {
            etSearch.setText("");
            backToCenter();
        } else if (id == R.id.tv_search_bt) {
            searchSuggession();
        } else if (id == R.id.iv_moto_center) {
            backToCenter();
        }

    }

    private void backToCenter() {
        updateLocCenter(LocationService.get().getLocatedInfo());
    }
}
